package com.example.dowertefense;

import android.annotation.SuppressLint;
import android.content.Context;
import android.util.AttributeSet;
import android.util.Log;
import android.view.View;
import android.widget.ImageView;
import android.widget.RelativeLayout;

import java.util.ArrayList;
import java.util.Random;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;

public class PlayGame extends View implements Runnable{

	private GameObj objs[];
	private int MaxObjs;
	private ArrayList<Turret> turrets;
	private int turretCounter;
	private Paint paint = null;
	private Thread thread = null;
	private int height;
	private int width;
	private boolean firstDraw = true;
	Canvas canvas = null;
	RelativeLayout rl;
	ImageView vi;
	private boolean pause = false;
	
	public PlayGame(Context context, AttributeSet attrs) {
		super(context, attrs);
		paint = new Paint();
		turrets = new ArrayList<Turret>();
		vi = (ImageView)findViewById(R.id.imageView28);
		turretCounter = 0;
	}
	
	public void Pause()
	{
		pause = !pause;
	}
	
	@SuppressLint("NewApi")
	public void addLayout(RelativeLayout rl1)
	{
		rl = rl1;
		vi = new ImageView(null);
		vi.setImageResource(R.drawable.ic_launcher);
		vi.setX(15);
		vi.setY(617);
		rl.addView(vi);
	}
	
	public void callMe(float x, float y)
	{
		Turret t = new Turret(x, y);
		turrets.add(t);
		t.setCanvas(canvas);
		turretCounter++;
	}
	
	public void onDraw(Canvas canvas)
	{
		if(firstDraw)
			FirstDraw(canvas);
		paint.setColor(Color.rgb(28, 124, 54));
		canvas.drawRect(0, 0, getWidth(), getHeight(), paint);
		paintEveryThing(canvas);
	}
	
	public void start()
	{
		if(thread == null)
			thread = new Thread(this);
		thread.start();
	}

	@SuppressLint("NewApi")
	@Override
	public void run() {
		try{
			Thread.sleep(1000);
		} catch (Exception e){}
		
		out:while(true)
		{
			
			int delayTime = 1000/20;
			long loopStartTime = System.currentTimeMillis();
			
			moveGameObjects();
			this.postInvalidate();
			
			long loopEndTime = System.currentTimeMillis();
			int loopTime = (int)(loopEndTime - loopStartTime);
			if(loopTime < delayTime)
			{
				try{
					Thread.sleep(delayTime - loopTime);
				}catch(Exception e){}
			}
		}
	}
	
	protected void paintEveryThing(Canvas g)
	{
		paintGameObjs(g, objs, MaxObjs);
	}
	
	@SuppressLint("NewApi")
	private void paintGameObjs(Canvas g, GameObj[] ar, int numAr)
	{
		for(int x=0; x < numAr; x++)
			if(ar[x].isAlive())
				ar[x].paintComponent(g);
		for(int x = 0; x < turretCounter; x++)
		{
			turrets.get(x).Draw(g);
		}
	}
	
	private void moveGameObjects()
	{
		if(!pause)
		{
			int d;
			for(int x=0; x < MaxObjs; x++)
			{
				objs[x].go();
			}
			for(int x=0; x < turretCounter; x++)
			{
				turrets.get(x).attack(objs, MaxObjs);
			}
		}
	}
	
	public void FirstDraw(Canvas g)
	{
		firstDraw = false;
		canvas = g;
		MaxObjs = 7;
		height = this.getHeight();
		width = this.getWidth();
		objs = new GameObj[MaxObjs];
		for(int x = 0; x < MaxObjs; x++)
		{
			objs[x] = new GameObj(width, height, 20, 500, x);
			objs[x].setBugColor(255, 0, 0);
		}
	}
	
	private class GameObj
	{
		protected int x, y; // integer x and y of bug center
		protected float rx, ry; // real x and y of bug center
		protected float attackx, attacky;
		protected int color; // current color
		protected int speedx; // number of units in a bug move x
		protected int speedy; // number of units in a bug move y
		protected int width; // width of the drawable area
		protected int height; // height of the drawable area
		protected int MAXDIRECTION=16; // directions in 360 degrees
		protected int R=255, G=255, B=255;// RGB colors, default is white
		protected boolean alive = true; // true if the bug is alive, false otherwise
		protected boolean p1, p2, p3, p4;
		protected float count = 0;
		protected int health = 30; 
		
		protected float x1, y1, x2, y2, x3, y3, x4, y4;
		
		public float getX()
		{
			return attackx;
		}
		
		public void IGotShot()
		{
			health -= 10;
			if(health == 0)
				alive = false;
		}
		
		public float getY()
		{
			return attacky;
		}
		
		public GameObj(int w, int h, int initx, int inity, int counter)
		{
			p1 = true;
			p2 = false;
			p3 = false;
			p4 = false;
			width = w;
			height = h;
			speedx = 4;
			x = initx;
			y = inity;
			rx = x;
			ry = y;
			count = counter;
		}
		
		public void go()
		{
			if(count > 0)
			{
				count = (float) (count - .1);
				return;
			}
			x += speedx;
			y += speedy;
			rx = x;
			ry = y;
			attackx = rx - 67;
			attacky = ry + 67;
		}
		public int returnx(){return x;}
		public int returny(){return y;}
		public boolean isAlive(){return alive;}
		public void makeDead(){alive = false;}
		
		public void setBugColor(int r, int g, int b){
			if (r < 256 && r >= 0) R = r;
			if (g < 256 && g >= 0) G = g;
			if (b < 256 && b >= 0) B = b;
		}
		
		public void paintComponent(Canvas g){
			paintObject(g);
		}
		
		public void paintObject(Canvas g)
		{
			paint.setColor(Color.rgb(R, G, B));
			paint.setStrokeWidth(0);
			Rect r;
			r = new Rect(x, y, x+12, y+12);
			g.drawRect(r, paint);
			if(rx >= 175 && p1)
			{
				rx = 175;
				x = 175;
				speedx = 0;
				speedy = -4;
				p1 = false;
				p2 = true;
			}
			else if(ry <= 90 && p2)
			{
				y = 90;
				ry = y;
				p3 = true;
				p2 = false;
				speedx = 4;
				speedy = 0;
			}
			else if(rx >= 340 && p3)
			{
				x = 340;
				rx = x;
				p4 = true;
				p3 = false;
				speedx = 0;
				speedy = 4;
			}
			else if(ry >= 600 && p4)
			{
				p1 = false;
				p4 = false;
				alive = false;
			}
		}
	}

	private class Turret
	{
		private float x;
		private float y;
		private Boolean attacked;
		private int attackReset;
		private Arrow arrow = null;
		Canvas c;
		
		public void setCanvas(Canvas g)
		{
			c = g;
		}
		
		public void Draw(Canvas g)
		{
			if(arrow != null)
			{
				arrow.go();
				arrow.paintComponent(g);
				if(!arrow.alive())
					arrow = null;
			}		
		}
		public Turret(float xpos, float ypos)
		{
			x = xpos;
			y = ypos;
			attacked = false;
			attackReset = 0;
		}
		
		public void attack(GameObj[] obj, int numOfObjs)
		{
			float xDis, yDis;
			if(attacked == false)
			{
				for(int i = 0; i < numOfObjs; i++)
				{
					if(obj[i].isAlive())
					{
						xDis = x - obj[i].getX();
						yDis = y  - obj[i].getY();
						if(-100 < xDis && xDis < 175)
						{
							if(-100 < yDis && yDis < 175)
							{
								if(arrow == null)
								{
									arrow = new Arrow(x, y - 148, obj[i]);
								}
							}
						}
					}
				}
			}
		}
	}
	
	private class Arrow
	{
		private float x, y, targetx, targety;
		GameObj target;
		boolean alive = false;
		public Arrow(float x, float y, GameObj target)
		{
			this.x = x;
			this.y = y;
			this.target = target;
			alive = true;
		}
		public void go()
		{
			targetx = target.getX() + 67;
			targety = target.getY() - 67;
			if(targetx < x)
				x = x - 7;
			else
				x = x + 7;
			if(targety < y)
				y = y - 7;
			else
				y = y + 7;
		}
		
		public void paintComponent(Canvas g){
			paintObject(g);
		}
		
		public void paintObject(Canvas g)
		{			
			paint.setColor(Color.rgb(0, 0, 255));
			paint.setStrokeWidth(0);
			Rect r;
			r = new Rect((int)x, (int) y, (int) x+7, (int)y+7);
			g.drawRect(r, paint);
			float x1, y1;
			x1 = x - (target.getX() + 67);
			y1 = y - (target.getY() - 67);
			if(-20 < x1 && x1 < 20)
			{
				if(-20 < y1 && y1 < 20)
				{
					alive = false;
					target.IGotShot();
				}
			}
		}
		public boolean alive()
		{
			if(alive)
				return true;
			else
				return false;
		}
	}
}
